import {
  ArgumentsHost,
  BadRequestException,
  Catch,
  ExceptionFilter,
  HttpException,
} from '@nestjs/common';
import { Response, Request } from 'express';
import { I18nService, I18nValidationException } from 'nestjs-i18n';

@Catch(HttpException)
export class AdminException implements ExceptionFilter {
  constructor(private readonly i18n: I18nService) {}

  catch(exception: any, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request: any = ctx.getRequest<Request>();
    let status = exception.getStatus();
    let errorMessage = exception.message;
    // 说明可以是验证管道抛出的异常
    if (exception instanceof BadRequestException) {
      const exceptionBody: any = exception.getResponse();
      if (typeof exceptionBody === 'object' && exceptionBody.message) {
        errorMessage = exceptionBody.message?.join('，');
        status = exceptionBody.statusCode;
      }
    } else if (exception instanceof I18nValidationException) {
      const errors = exception.errors;
      errorMessage = errors
        .map((error) => this.formatErrorMessage(error, request.i18nLang))
        .join('；');
    }
    response.status(status).render('error', {
      message: errorMessage,
    });

    return exception;
  }

  formatErrorMessage(error: any, lang) {
    const { value, property, constraints } = error;
    const constraintsValues = Object.values(constraints);
    const formatedMessage = constraintsValues.map(
      (constraintsValue: string) => {
        const [key, params] = constraintsValue.split('|');
        if (params) {
          const parsedParams = JSON.parse(params);
          return this.i18n.translate(key, {
            lang,
            args: parsedParams,
          });
        }
      },
    );

    return `${property}: ${value} ${formatedMessage.join('，')}`;
  }
}
